<template>
  <a-skeleton :loading="loading" active avatar :paragraph="{ rows: 20 }">
    <article v-if="article">
      <header class="article__header">
        <img class="avatar" src="@/assets/img/dashuaibi.jpg" />
        <div class="article__infos">
          <span class="author">Soveilove</span>
          <sup class="role-tag">靓仔</sup>
          <div>
            <time>发布于{{ article.create_time }}</time>
            <span class="read_total"
              >阅读&nbsp;&nbsp;{{ article.read_num }}</span
            >
          </div>
        </div>
      </header>
      <main class="article__main">
        <el-image class="article__poster" :src="article.poster" />
        <h2>{{ article.article_name }}</h2>
        <!-- v-html 解析出真正的html -->
        <section class="md-preview" v-html="safeContent"></section>
      </main>
      <div class="copyright">
        <p>
          本文链接：<a :href="Link">{{ Link }}</a>
          <br />
          版权声明：本文由<strong>Soveilove</strong>原创，发表于{{
            article.create_time
          }}，如需转载，请联系作者授权！
        </p>
      </div>
      <div class="reward__wrapper">
        <p class="reward__tips">您的支持将鼓励我继续创作！</p>
        <a-button type="primary" @click="isMoneyValue = true"
          ><span>赏</span></a-button
        >
      </div>
    </article>
    <a-empty v-else />
  </a-skeleton>
  <div class="pre-next-wrap">
    <div class="prev" v-if="prevArticle">
      <SwapLeftOutlined />
      <span>上一篇:</span>
      <router-link :to="`/article/${prevArticle.id}`"
        ><span>{{ prevArticle.article_name }}</span></router-link
      >
    </div>
    <div class="next" v-if="nextArticle">
      <SwapRightOutlined />
      <span>下一篇:</span>
      <router-link :to="`/article/${nextArticle.id}`"
        ><span>{{ nextArticle.article_name }}</span>
      </router-link>
    </div>
  </div>
  <div class="comment__trigger">
    <a-button type="primary" @click="isCommentValue = true">查看评论</a-button>
  </div>

  <a-modal v-model:visible="isMoneyValue" :footer="null">
    <div class="reward-popup__wrapper">
      <p class="reward__tips">感谢您的赞赏支持！</p>
      <img class="payme" src="@/assets/img/dashuaibi.jpg" />
    </div>
  </a-modal>

  <a-drawer
    v-model:visible="isCommentValue"
    width="100%"
    class="drawer-comment"
  >
    <template #title>
      <span>评论区</span>
      <EditOutlined style="margin-left: 10px" @click="isShowUserInfo" />
    </template>
    <comments ref="commentsRef" />
  </a-drawer>

  <aside class="aside-icons">
    <icon-svg
      class="icon--aside icon-edit"
      icon="edit"
      v-if="isAuthed"
    ></icon-svg>
    <icon-svg
      class="icon--aside icon-message"
      icon="leave-message"
      @click="isCommentValue = true"
    ></icon-svg>
  </aside>
</template>

<script lang="ts">
import { marked } from 'marked';
// hljs 按需加载

import hljs from 'highlight.js/lib/core';
import javascript from 'highlight.js/lib/languages/javascript';
import html from 'highlight.js/lib/languages/xml';
import css from 'highlight.js/lib/languages/css';
import shell from 'highlight.js/lib/languages/shell';
import json from 'highlight.js/lib/languages/json';
import plaintext from 'highlight.js/lib/languages/plaintext';
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('html', html);
hljs.registerLanguage('css', css);
hljs.registerLanguage('shell', shell);
hljs.registerLanguage('json', json);
hljs.registerLanguage('plaintext', plaintext);

import {
  computed,
  defineComponent,
  onBeforeUnmount,
  onMounted,
  ref,
} from 'vue';
import {
  SwapLeftOutlined,
  SwapRightOutlined,
  EditOutlined,
} from '@ant-design/icons-vue';
import { Drawer, Modal } from 'ant-design-vue';
import Comments from '../messages/comments.vue';
import { useRoute, useRouter } from 'vue-router';
import { articleService } from '@/api/article';
import { useAsyncLoading } from '@/hooks';
import { ArticleDTO, prevOrnextDTO } from '@/bean/dto';
import { format } from '@/utils/date-utils';
import Mymain from '@/utils/maxBy';

import DOMPurify from 'dompurify';
import { useStore } from '@/store';

export default defineComponent({
  name: 'Article',
  components: {
    SwapLeftOutlined,
    SwapRightOutlined,
    EditOutlined,
    Comments,
    [Modal.name]: Modal,
    [Drawer.name]: Drawer,
  },
  setup() {
    // vuex(类型验证)
    const store = useStore();
    const isAuthed = computed(() => store.getters.isAuthed);

    // router
    const router = useRouter();
    const route = useRoute();

    // 在这里类型转换吧,就不用后面疯狂+了
    const articleid = computed(() => +route.params.id);

    const article = ref<ArticleDTO>();
    const Link = window.location.href;
    const safeContent = ref();

    // 定时器的标识
    let readVolumeTimer: any = null;

    // 获取文章数据
    const handleGetArticle = async () => {
      const res = await articleService.detail({ id: articleid.value });

      res.data.create_time = format(res.data.create_time, 'YYYY年M月D日');
      article.value = res.data;
      // 主体部分
      const markedcontent = marked.parse(res.data.article_text);

      // 老规矩,防xss
      safeContent.value = DOMPurify.sanitize(markedcontent);

      // 阅读量
      startReadingVolume();
    };

    const { trigger: getArticle, loading } = useAsyncLoading(handleGetArticle);

    // 增加阅读量
    const startReadingVolume = () => {
      readVolumeTimer = window.setTimeout(() => {
        articleService.updateReadNum(articleid.value);
      }, 3000);
    };
    const claerReadingVolume = () => {
      if (readVolumeTimer) {
        clearTimeout(readVolumeTimer);
      }
    };

    const setMarkedOptions = () => {
      const renderer = new marked.Renderer();
      renderer.link = function customLink(href, title, text) {
        return `<a class="link" href="${href}" target="_blank" title="${text}">${text}</a>`;
      };
      renderer.image = function customImage(href, title, text) {
        return (
          `<a class="img-wrapper" href="${href}" target="_blank" title="${text}">` +
          `<img src="${href}" alt="${text}">` +
          '</a>'
        );
      };
      marked.setOptions({
        renderer,
        highlight: function (code: string, lang: string) {
          const language = hljs.getLanguage(lang) ? lang : 'plaintext';
          return hljs.highlight(code, { language }).value;
        },
        pedantic: false,
        gfm: true,
        breaks: false,
        sanitize: false,
        smartLists: true,
        smartypants: false,
        xhtml: false,
      });
    };

    // 前后两篇文章信息
    const prevArticle = ref<prevOrnextDTO>();
    const nextArticle = ref<prevOrnextDTO>();

    // 我认为直接一个pormiseAll过去,接受数据
    const GetprevOrnextArticle = async () => {
      const res = await articleService.neighbors({ id: articleid.value });
      const result = res.data;
      if (result.length > 0) {
        switch (result.length) {
          case 1:
            const singleArticle = result[0];
            singleArticle.id > articleid.value
              ? (nextArticle.value = singleArticle)
              : (prevArticle.value = singleArticle);
            break;
          case 2:
            // 像弄出一个minBy的函数,发现定义完善点会比较难
            prevArticle.value = Mymain.minBy(result, 'id');
            nextArticle.value = Mymain.maxBy(result, 'id');
            break;
          default:
            break;
        }
      }
    };

    // 生命钩子
    onMounted(() => {
      setMarkedOptions();
      getArticle();

      GetprevOrnextArticle();
    });

    onBeforeUnmount(() => {
      claerReadingVolume();
    });

    // 给小费
    const isMoneyValue = ref(false);

    // 评论
    const isCommentValue = ref(false);
    const commentsRef = ref();

    // 修改个人信息
    const isShowUserInfo = () => {
      commentsRef.value.ismodalVisible = true;
    };

    // 去后台编辑一下(该功能还没开发)

    return {
      isAuthed,
      article,
      isMoneyValue,
      isCommentValue,
      commentsRef,
      safeContent,
      isShowUserInfo,
      loading,
      Link,
      prevArticle,
      nextArticle,
    };
  },
});
</script>

<style scoped lang="scss" src="./index.scss"></style>
<style lang="scss" scoped src="./md-render.scss"></style>
